package com.zj.z11select.service.impl;


import com.alibaba.fastjson.JSON;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import com.qcloud.cos.utils.Md5Utils;
import com.qcloud.cos.utils.UrlEncoderUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.HmacUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author ZhouJie
 * @date 2021-11-10 21:12
 */
@Slf4j
@Service
public class TestServiceImpl {

    @Autowired
    private RestTemplate restTemplate;

    private static final String SECRET_ID = "AKIDqVu3NcaIjuoRoukJbfU4OSHq89uObXCa";
    private static final String SECRET_KEY = "91cx1oOkqgGciY8SXMvFK9h03qOgiU0G";

    /** COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224 */
    private static final String REGION_NAME = "ap-shanghai";

    /**存储桶名称，格式：BucketName-APPID */
    private static final String BUCKET_NAME = "youzantest-1305846390";

    private COSClient createCOSCClient(){
        // 1 初始化用户身份信息(secretId, secretKey)。
        // SECRETID和SECRETKEY请登录访问管理控制台 https://console.cloud.tencent.com/cam/capi 进行查看和管理
        COSCredentials cred = new BasicCOSCredentials(SECRET_ID, SECRET_KEY);

        // 2 设置 bucket 的地域
        // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
        Region region = new Region("ap-shanghai");
        ClientConfig clientConfig = new ClientConfig(region);

        // 这里建议设置使用 https 协议
        // 从 5.6.54 版本开始，默认使用了 https
        clientConfig.setHttpProtocol(HttpProtocol.https);
        // 3 生成 cos 客户端。
        return new COSClient(cred, clientConfig);
    }

    public void createBucket() {
        //存储桶名称，格式：BucketName-APPID
        CreateBucketRequest createBucketRequest = new CreateBucketRequest(BUCKET_NAME);
        // 设置 bucket 的权限为 Private(私有读写)、其他可选有 PublicRead（公有读私有写）、PublicReadWrite（公有读写）
        createBucketRequest.setCannedAcl(CannedAccessControlList.Private);
        try {
            Bucket bucketResult = this.createCOSCClient().createBucket(createBucketRequest);
            log.info("createBucket,result:{}", JSON.toJSONString(bucketResult));
        } catch (CosServiceException serverException) {
            serverException.printStackTrace();
        } catch (CosClientException clientException) {
            clientException.printStackTrace();
        }

    }

    private String getAuthoriationStr(String host, String formatMethod,String resourceUrl,String formatParameters,String qHeaderListStr,String formatHeaders){
        String formatStr = formatMethod + "\n" + resourceUrl + "\n" + formatParameters + "\n" + formatHeaders + "\n";
        log.info("formatStr:\n{}",formatStr);

        String hashFormatStr = DigestUtils.sha1Hex(formatStr);
        //签名开始时间,过期时间
        Date startTime = new Date();
        Date endTime = new Date(startTime.getTime() + 3600 * 1000);
        String qKeyTimeStr, qSignTimeStr;
        qKeyTimeStr = qSignTimeStr = buildTimeStr(startTime, endTime);
        String signKey = HmacUtils.hmacSha1Hex(SECRET_KEY, qKeyTimeStr);
        String stringToSign = "sha1" + "\n" + qSignTimeStr + "\n" + hashFormatStr + "\n";
        log.info("stringToSign:\n{}",stringToSign);

        String signature = HmacUtils.hmacSha1Hex(signKey, stringToSign);
        String authoriationStr = "q-sign-algorithm" + "=" + "sha1" +
                "&" + "q-ak" + "=" + SECRET_ID +
                "&" + "q-sign-time" + "=" + qSignTimeStr +
                "&" + "q-key-time" + "=" + qKeyTimeStr +
                "&" + "q-header-list" + "=" + qHeaderListStr +
                "&" + "q-url-param-list" + "=" + "" +
                "&" + "q-signature" + "=" + signature;
        log.info("authoriationStr:\n{}",authoriationStr);

        return authoriationStr;
    }


    public void queryBucket1(){
        String host = "service.cos.myqcloud.com";
        //公共参数签名
        HttpHeaders headers = new HttpHeaders();
        String authoriationStr = getAuthoriationStr(host, "get", "/", "","host", "host=service.cos.myqcloud.com");
        headers.set("Authorization",authoriationStr);
        //注意YouZan容器无需host请求头
        headers.set(HttpHeaders.HOST,host);

        String url = "https://service.cos.myqcloud.com/";
        HttpEntity<String> httpEntity = new HttpEntity<>(headers);
        String body = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class).getBody();
        //只能返回xml形式,如果需要使用则要进行手动转换
        log.info("body:{}",body);
    }

    public void uploadBucket1()   {

        try {
            // 指定要上传的文件
            File localFile = new File("C:\\Users\\ZHOUJIE\\Desktop\\img.jpg");

            String host = "youzantest-1305846390.cos.ap-shanghai.myqcloud.com";
            //公共参数签名
            HttpHeaders headers = new HttpHeaders();
            headers.setContentLength(localFile.length());
            String md5 = Md5Utils.md5AsBase64(localFile);
            headers.set("Content-MD5",md5);
            //注意YouZan容器无需host请求头
            headers.set(HttpHeaders.HOST,host);

            String qHeaderListStr = "content-length;content-md5;host";
            String formatHeaders = UrlEncoderUtils.encode("content-length") + "=" + UrlEncoderUtils.encode(localFile.length()+"")
                    + "&" + UrlEncoderUtils.encode("content-md5") + "=" +  UrlEncoderUtils.encode(md5)
                    + "&" + UrlEncoderUtils.encode("host") + "=" + UrlEncoderUtils.encode(host);

            // 指定文件上传到 COS 上的路径，即对象键。例如对象键为folder/picture.jpg，则表示将文件 picture.jpg 上传到 folder 路径下
            String key = "/img/girl111.jpg";

            String authorization = getAuthoriationStr(host, "put",key,"", qHeaderListStr,formatHeaders);
            headers.set("Authorization",authorization);
            String url = "https://youzantest-1305846390.cos.ap-shanghai.myqcloud.com" + key;
            FileSystemResource resource = new FileSystemResource(localFile);
            HttpEntity entity = new HttpEntity<>(resource, headers);
            String body = restTemplate.exchange(url, HttpMethod.PUT, entity, String.class).getBody();

            log.info("uploadBucket:{}",body);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void queryObjectListForBucket(){
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
        // 设置bucket名称
        listObjectsRequest.setBucketName(BUCKET_NAME);
        // prefix表示列出的object的key以prefix开始
        listObjectsRequest.setPrefix("img/");
        // deliter表示分隔符, 设置为/表示列出当前目录下的object, 设置为空表示列出所有的object
        listObjectsRequest.setDelimiter("/");
        // 设置最大遍历出多少个对象, 一次listobject最大支持1000
        listObjectsRequest.setMaxKeys(1000);
        ObjectListing objectListing = null;
        do {
            try {
                objectListing = this.createCOSCClient().listObjects(listObjectsRequest);
            } catch (CosServiceException e) {
                e.printStackTrace();
                return;
            } catch (CosClientException e) {
                e.printStackTrace();
                return;
            }
            // common prefix表示表示被delimiter截断的路径, 如delimter设置为/, common prefix则表示所有子目录的路径
            List<String> commonPrefixs = objectListing.getCommonPrefixes();

            // object summary表示所有列出的object列表
            List<COSObjectSummary> cosObjectSummaries = objectListing.getObjectSummaries();
            for (COSObjectSummary cosObjectSummary : cosObjectSummaries) {
                // 文件的路径key
                String key = cosObjectSummary.getKey();
                // 文件的etag
                String etag = cosObjectSummary.getETag();
                // 文件的长度
                long fileSize = cosObjectSummary.getSize();
                // 文件的存储类型
                String storageClasses = cosObjectSummary.getStorageClass();

                log.info("key:{},etag:{},fileSize:{},storageClasses:{}",key, etag, fileSize, storageClasses);
            }

            String nextMarker = objectListing.getNextMarker();
            listObjectsRequest.setMarker(nextMarker);
        } while (objectListing.isTruncated());
    }

    /**
     * 计算时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return xxx;xxx 格式化
     */
    private String buildTimeStr(Date startTime, Date endTime) {
        StringBuilder strBuilder = new StringBuilder();
        long startTimestamp = startTime.getTime() / 1000;
        long endTimestamp = endTime.getTime() / 1000;
        strBuilder.append(startTimestamp).append(";").append(endTimestamp);
        return strBuilder.toString();
    }
}


